#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>

#include <sys/stat.h>

#include "help/query.h"

int main(int argc, char* argv[]) {
    if (argc < 3) {
        return 1;
    }

    char* user = argv[1];
    char* unit = argv[2];
    char* root = getenv("RELAT_ROOT");

    float user_x = 0, user_y = 0, user_z = 0;
    query_user_position(user, &user_x, &user_y, &user_z);

    float x = 0, y = 0, z = 0;
    query_unit_position(user, unit, &x, &y, &z);

    DIR* root_dir;
    while((root_dir = opendir(root)) == NULL) {
        perror("could not open root dir");
        return 1;
    }

    struct dirent* root_entry;
    while ((root_entry = readdir(root_dir)) != NULL) {
        char root_entry_path[256];
        sprintf(root_entry_path, "%s/%s", root, root_entry->d_name);

        struct stat root_entry_stat;
        if (stat(root_entry_path, &root_entry_stat) != 0) {
            perror("Could not read stats from entry");
            return 1;
        }

        if (S_ISDIR(root_entry_stat.st_mode)) {
            continue;
        }

        // TODO: better check whether directory is really a user
        if (root_entry->d_namlen < 3) {
            continue;
        }

        if (strcmp(root_entry->d_name, user) == 0) {
            continue;
        }

        char* another_user = root_entry->d_name;

        float another_user_x = 0, another_user_y = 0, another_user_z = 0;
        query_user_position(another_user, &another_user_x, &another_user_y, &another_user_z);

        char another_user_dir_name[256];
        sprintf(another_user_dir_name, "%s/%s", root, another_user);

        DIR* another_user_dir;
        if ((another_user_dir = opendir(another_user_dir_name)) == NULL) {
            perror("could not open user directory");
            return 1;
        }

        struct dirent* another_user_entry;
        while((another_user_entry = readdir(another_user_dir)) != NULL) {
            char entry_path[256];
            sprintf(entry_path, "%s/%s", root, another_user_entry->d_name);

            struct stat* entry_stat;
            if (stat(entry_path, entry_stat) != 0) {
                perror("Could not read stats from entry");
                return 1;
            }

            if (S_ISDIR(entry_stat->st_mode)) {
                continue;
            }

            // TODO: better check whether directory is really a user
            if (another_user_entry->d_namlen < 3) {
                continue;
            }

            char* another_unit = another_user_entry->d_name;

            float another_x = 0, another_y = 0, another_z = 0;
            query_unit_position(another_user, another_unit, &another_x, &another_y, &another_z);

            another_x += another_user_x - user_x;
            another_y += another_user_y - user_y;
            another_z += another_user_z - user_z;

            float dx = x - another_x;
            float dy = y - another_y;
            float dz = z - another_z;

            float distance2 = dx*dx + dy*dy + dz*dz;

            // TODO: get rid of static view distance
            if (distance2 < 10 * 10) {
                printf("%s: %s/%s: %.3f %.3f %.3f\n", unit, another_user, another_unit, another_x, another_y, another_z);
            }
        }

        closedir(another_user_dir);
    }

    closedir(root_dir);
    
    return 0;
}
